/*******************************************************************************
 * Copyright (c) 2012, 2017 IBM Corp.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 *
 * The Eclipse Public License is available at
 *   http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 *   http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *    Ian Craggs - initial contribution
 *******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"
#include "cJSON.h"

#define ADDRESS "tcp://192.168.0.109:1883"
#define CLIENTID "ExampleClientSub"
#define TOPIC_UP "up"
#define TOPIC_DOWN "down"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L

volatile MQTTClient_deliveryToken deliveredtoken;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    //printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int i;
    char *payloadptr;

   // printf("Message arrived\n");
   // printf("     topic: %s\n", topicName);
   // printf("   message: ");
#if 0
    payloadptr = message->payload;
    for (i = 0; i < message->payloadlen; i++)
    {
        putchar(*payloadptr++);
    }
    putchar('\n');
#endif
    cJSON *item = NULL;
    cJSON *root = cJSON_Parse(message->payload);
    if (!root)
    {
        printf("Error before:[%s]\n", cJSON_GetErrorPtr());
    }
    else
    {
        item = cJSON_GetObjectItem(root, "name");
        //printf("name:%s\n", item->valuestring);

        item = cJSON_GetObjectItem(root, "age");
        //printf("age:%d\n", item->valueint);

        item = cJSON_GetObjectItem(root, "msg");
        //printf("msg: %s\n", item->valuestring);
    }
    printf("recv msg = %s\n", (char *)message->payload);

    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}

int main(int argc, char *argv[])
{
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;

    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;

    int rc;
    int ch;

    MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);

    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    MQTTClient_subscribe(client, TOPIC_DOWN, QOS);
    char buf[128] = {0};
    // 创建对象
         
    printf("\n\t--------------欢迎来到基于MQTT协议的聊天室[q或Q退出]-------------------\n");

    while (1)
    {
      
        printf("please input >>>\n");
          memset(buf,0,128);
          
        fgets(buf, 128, stdin);
        if(buf[strlen(buf)-1]=='\n')
            buf[strlen(buf)-1]=0;
      /*  do
        {
            
           ch=getchar();
        } while (ch != 'Q' &&ch != 'q');


  */
        cJSON *Obj = cJSON_CreateObject();//放到循环中，不然就重复了
       if(strstr(buf,"q")!=NULL||strstr(buf,"Q")!=NULL)
       break;
   
        cJSON_AddItemToObject(Obj, "name", cJSON_CreateString("zhangsan"));
        cJSON_AddItemToObject(Obj, "age", cJSON_CreateNumber(16));
        cJSON_AddItemToObject(Obj, "msg", cJSON_CreateString(buf));

        pubmsg.payload = cJSON_Print(Obj);
        pubmsg.payloadlen = (int)strlen(cJSON_Print(Obj));
        pubmsg.qos = QOS;
        pubmsg.retained = 0;
        MQTTClient_publishMessage(client, TOPIC_UP, &pubmsg, &token);
        // printf("Waiting for up to %d seconds for publication of %s\n"
        //     "on topic %s for client with ClientID: %s\n",
        //    (int)(TIMEOUT / 1000), PAYLOAD, TOPIC, CLIENTID);
        // rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
        // printf("Message with delivery token %d delivered\n", token);
        //printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
             //  "Press Q<Enter> to quit\n\n",
             //  TOPIC_DOWN, CLIENTID, QOS);
        cJSON_Delete(Obj);//同时还要删除对象
        
    }
   
    MQTTClient_unsubscribe(client, TOPIC_DOWN);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}
